{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Regression: The TensorFlow Way\n",
    "\n",
    "For this script, we introduce how to perform linear regression in the context of TensorFlow.\n",
    "\n",
    "We will solve the linear equation system:\n",
    "\n",
    "$$ y = Ax + b$$\n",
    "\n",
    "With the Sepal length (y) and Petal width (x) of the Iris data.\n",
    "\n",
    "Performing linear regression in TensorFlow is a lot easier than trying to understand Linear Algebra or Matrix decompositions for the prior two recipes.  We will do the following:\n",
    "\n",
    " 1. Create the linear regression computational graph output. This means we will accept an input, $x$, and generate the output, $Ax + b$.\n",
    " 2. We create a loss function, the L2 loss, and use that output with the learning rate to compute the gradients of the model variables, $A$ and $b$ to minimize the loss.\n",
    " \n",
    "The benefit of using TensorFlow in this way is that the model can be routinely updated and tweaked with new data incrementally with any reasonable batch size of data.  The more iterative we make our machine learning algorithms, the better.\n",
    "\n",
    "We start by loading the necessary libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from sklearn import datasets\n",
    "from tensorflow.python.framework import ops\n",
    "ops.reset_default_graph()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We create a graph session."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "sess = tf.Session()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we load the Iris data from the Scikit-Learn library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the data\n",
    "# iris.data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]\n",
    "iris = datasets.load_iris()\n",
    "x_vals = np.array([x[3] for x in iris.data])\n",
    "y_vals = np.array([y[0] for y in iris.data])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With most TensorFlow algorithms, we will need to declare a batch size for the placeholders and operations in the graph.  Here, we set it to 25.  We can set it to any integer between 1 and the size of the dataset.\n",
    "\n",
    "For the effect of batch size on the training, see [Chapter 2: Batch vs Stochastic Training](https://github.com/nfmcclure/tensorflow_cookbook/tree/master/02_TensorFlow_Way/06_Working_with_Batch_and_Stochastic_Training)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Declare batch size\n",
    "batch_size = 25"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now initialize the placeholders and variables in the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize placeholders\n",
    "x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)\n",
    "y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)\n",
    "\n",
    "# Create variables for linear regression\n",
    "A = tf.Variable(tf.random_normal(shape=[1,1]))\n",
    "b = tf.Variable(tf.random_normal(shape=[1,1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We add the model operations (linear model output) and the L2 loss."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Declare model operations\n",
    "model_output = tf.add(tf.matmul(x_data, A), b)\n",
    "\n",
    "# Declare loss function (L2 loss)\n",
    "loss = tf.reduce_mean(tf.square(y_target - model_output))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to tell TensorFlow how to optimize and back propagate the gradients.  We do this with the standard Gradient Descent operator (`tf.train.GradientDescentOptimizer`), with the learning rate argument of $0.05$.\n",
    "\n",
    "Then we initialize all the model variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Declare optimizer\n",
    "my_opt = tf.train.GradientDescentOptimizer(0.05)\n",
    "train_step = my_opt.minimize(loss)\n",
    "\n",
    "# Initialize variables\n",
    "init = tf.global_variables_initializer()\n",
    "sess.run(init)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We start our training loop and run the optimizer for 100 iterations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Step #25 A = [[2.603232]] b = [[2.1924005]]\n",
      "Loss = 1.9421344\n",
      "Step #50 A = [[1.9330357]] b = [[3.2180264]]\n",
      "Loss = 0.81023157\n",
      "Step #75 A = [[1.5262333]] b = [[3.8126156]]\n",
      "Loss = 0.51520616\n",
      "Step #100 A = [[1.2772702]] b = [[4.1850147]]\n",
      "Loss = 0.17318392\n"
     ]
    }
   ],
   "source": [
    "# Training loop\n",
    "loss_vec = []\n",
    "for i in range(100):\n",
    "    rand_index = np.random.choice(len(x_vals), size=batch_size)\n",
    "    rand_x = np.transpose([x_vals[rand_index]])\n",
    "    rand_y = np.transpose([y_vals[rand_index]])\n",
    "    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})\n",
    "    temp_loss = sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})\n",
    "    loss_vec.append(temp_loss)\n",
    "    if (i+1)%25==0:\n",
    "        print('Step #' + str(i+1) + ' A = ' + str(sess.run(A)) + ' b = ' + str(sess.run(b)))\n",
    "        print('Loss = ' + str(temp_loss))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We pull out the optimal coefficients and get the best fit line."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the optimal coefficients\n",
    "[slope] = sess.run(A)\n",
    "[y_intercept] = sess.run(b)\n",
    "\n",
    "# Get best fit line\n",
    "best_fit = []\n",
    "for i in x_vals:\n",
    "  best_fit.append(slope*i+y_intercept)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot the results with Matplotlib.  Along with the linear fit, we will also plot the L2 loss over the model training iterations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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bNhQqcwRI0Z4enq6v/fee757925ftWqVN2rUyIcMGVL+a/7jjz/2pk2bevfu3X3NmjU11nP06NEOeLdu3TwjI8MXLlwYc9n9WyMiyUBBIHFVWlrqkyZN8m9961vl4w1t27b1zMxMHzhwYK27nKLWrVvnzZo1c8BTU1O9VatW3qhRowPGLz744ANv0qSJd+3atdqxjegpsRdccIFv3LjRc3JyvGfPnlV2ab344ouekpLi48aNO2Af//rXv1Y6m0rkaKIgkHpRVlbmCxYs8CeeeMKvvPJKP++88w75dNMNGzb4K6+84iNHjvQLLrjAJ06cWOVyc+bM8WbNmnmnTp3KT4Pdv07nnXeeN2nSpLzlMH36dAf8hhtuqLRsQUGBN23a1FNSUjwjI8Pnz59fXsZNN93kgLdr187nzp17SPskkkgKAklq+fn53qJFC8/IyPBLL73U33jjDV+xYoWPGzfOhw8f7oA/+eSTlda54447HPDrrrvOd+3a5Xv37vW+fft6s2bNfN68ed6xY0fv0qWLFxUV+e9+9zsH/Oqrr/ZOnTp5Zmamv/LKK4dc35KSEt++ffvh7rbIQVEQSNJbtmyZ/+IXv/BWrVpVuvq6bdu2fttttx3QPVVSUuJ33323A37yySf79ddf74C/9NJL7u7+4Ycfelpamh933HEO+DXXXONlZWW+ceNG/853vuOAX3755T579uyDOgtp27Zt3q9fP8/NzfWioqI6/TuoSVFRkV9++eV+5513+rZt2+p125J4CgIJjT179viUKVP8iSee8EWLFtX4JT116lRv3rx5+Zd9RY8++qgD/r3vfc/37dtXPn3Xrl3+q1/9yps2beqA9+7d28eOHVvtabTRug0cONAbNGjgqampfvnll1eaP2rUKD/ppJM8Pz//IPe6sgULFvgdd9zhEydO9L1797p7JCiPO+44T01NdcBzc3N96tSph7UdObooCESqUVBQ4Pfdd98B3TVlZWX+0Ucf+Z49e6pcb9u2bT527NjyQfJWrVr5Pffc4/PmzTvg135paalfdtll5RfM3XfffZVaII888ogDnpGR4RkZGf7cc8/VWO99+/b57Nmzfdq0aT5lyhR/+umn/YwzznDAzaz8C/+ee+7xFi1aeKtWrfyf//ynv//++96zZ8/y+1X95Cc/8UceecQ/+eSTA7axd+/e8lN742H16tX+y1/+0keNGuXLli2L23ZEQSASV2VlZT5z5ky/6KKLyr+AAW/evLl3797dTzzxRO/evbsD/sc//tHdI1/ip512mrdo0cL/8Ic/OOA/+MEPfP369d6/f38HfMSIEX7ffff5/fff7w8++KC/9NJLPmfOHF+4cKGPHDnS27VrV6kbDPCuXbv66NGjffPmzf7aa6/52Wef7YD36NGj0mD6nj17fPTo0T5o0CDPyckpX3/w4MH+3nvv+fLly/2uu+7yNm3aeEZGhl955ZX+r3/9K2YLq6yszBcvXuz333+/Dxo0yC+88EK/7LLL/IYbbvAXXnhwDQQdAAAL7UlEQVThgGAsLi72u+++2zMzM8tbKYD36tXLL7zwQh84cKCfe+65PmbMmIO+AHD37t3+/vvv+0svveRLly496LPWDmY78So7HmobBHoegchh+uKLL1iwYAErV66koKCArVu3sm/fPvbu3Uv//v255ZZbym/7/dlnn3HyySeza9cuBg8ezOTJk8nIyKCkpIQ777yTRx99lNLS0iq306BBA4YOHcpVV11Fx44dSUtLIzMzkxNPPJEGDSo/Y2rJkiXk5uZW+eyJqA0bNjB+/HjGjBnDpk2bAEhJSeHCCy+kffv2TJw4keLiYrp06UKXLl3o0KEDLVq0YMuWLWzevJnly5ezfPlyAE466SRSUlLYvn07mzZt4uuvvyYlJYW+fftiZmzatIl169axc+dOrrjiCv7whz8AMHnyZKZOncqWLVtIT09nx44dfPLJJ/z85z/nscceIyUlpcq6uzuffvopr776KtOnT2fevHns2bOnfH6zZs3o27cvAwcOZOjQoZxwwgkxH+taW6+88gr/+Z//Sffu3Zk0aRLHHHPMYZVXH2r7PAIFgUg9e/nll3nzzTf585//TMOGDSvNKy0txd0pKytj9+7drF69ms8//5yvvvqKwYMH0759+zqvz+7du3n++efZsmULV1xxRfk2tm/fzgsvvMCMGTNYt24d69atY+vWrbRo0YJWrVrRoUMHhgwZwvDhwyvVq7S0lHnz5vH666/z3nvvkZmZSXZ2Njk5OVxxxRWcdtppMetSVlbGyJEjefDBBxk2bBj33XcfCxcuZMGCBWzYsIGSkhL27dvH4sWLWbFiBQB5eXmcffbZnHXWWXTq1Il///vfzJ07l9mzZ5c/5rVjx46ceOKJdOvW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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot the result\n",
    "plt.plot(x_vals, y_vals, 'o', label='Data Points')\n",
    "plt.plot(x_vals, best_fit, 'r-', label='Best fit line', linewidth=3)\n",
    "plt.legend(loc='upper left')\n",
    "plt.title('Sepal Length vs Petal Width')\n",
    "plt.xlabel('Petal Width')\n",
    "plt.ylabel('Sepal Length')\n",
    "plt.show()\n",
    "\n",
    "# Plot loss over time\n",
    "plt.plot(loss_vec, 'k-')\n",
    "plt.title('L2 Loss per Generation')\n",
    "plt.xlabel('Generation')\n",
    "plt.ylabel('L2 Loss')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
